package de.fsujena.chat_pi.client;

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import de.fsujena.chat_pi.connection.*;
import de.fsujena.chat_pi.message.*;
import de.fsujena.chat_pi.message.SysMessage.CATEGORY;
import de.fsujena.chat_pi.message.SysMessage.MESSAGE;



public class ConnectionThread extends Thread {
	public InputStream in = null;
	public OutputStream out = null;
	public boolean greeting=false;
	public boolean reading=false;
	public String username;
	public String password;
	public Client mainThread;
	Socket server;
	List<TextMessage> msgArray=new ArrayList<TextMessage>();
	Connector connector;
	
	ObjectInputStream ois;
	ObjectOutputStream oos;
	
	BufferedReader bin;
	BufferedWriter bout;
	PrintWriter pout;

	/**
	 * @param args
	 */
	public ConnectionThread(String ip, int port) throws IOException {
		server = new Socket(ip, port);
		connector=new Connector(server,true,true);			
		connector.init();
		bin=connector.bin;
		bout=connector.bout;
		pout=connector.pout;
		
		ois = connector.ois;
		oos = connector.oos;
		
	}

	/* (non-Javadoc)
	 * @see java.lang.Thread#run()
	 */
	/* (non-Javadoc)
	 * @see java.lang.Thread#run()
	 */
	@Override
	public void run() {
		// TODO Auto-generated method stub
		reading=true;
		while (reading) {
			
			Object inputObject;
				try {
					inputObject = connector.readGeneralObject();
				

			if (inputObject instanceof TextMessage){
				TextMessage tempObj= (TextMessage)inputObject;
				tempObj.setReceived(new Date());
				System.out.println("["+tempObj.getSenderUsername()+"] "+tempObj.getMessageText());
				msgArray.add(tempObj);
				//TODO proper textmessage handling (e.g. save messages in history)				
				}	
			else if (inputObject instanceof SysMessage) {
				
				SysMessage sysMessage = (SysMessage) inputObject;
				
				switch (sysMessage.getMessage()) {
				case REQUEST_USERNAME:
					sendSysMessage(CATEGORY.LOGIN,MESSAGE.SEND_USERNAME,username);
					break;
				case REQUEST_PASSWORD:
					sendSysMessage(CATEGORY.LOGIN,MESSAGE.SEND_PASSWORD,password);
					break;
				case CONNECTED:
					System.out.println("connected to server "+server.getInetAddress()+" on port:"+server.getPort());
					break;
				case NOT_LOGGED_IN:
					System.out.println("not logged in please log in or register");
					break;
				case USERNAME_UNKNOWN:
					System.out.println("user unknown please register");
					break;
				case LOGGED_IN:
					System.out.println("your are now logged in");
					break;
				case PASSWORD_WRONG:
					System.out.println("incorrect password please try to login again");
					break;
				case REQUEST_NEW_USERNAME:
					sendSysMessage(CATEGORY.REGISTRATION, MESSAGE.SEND_NEW_USERNAME, username);
					break;
				case REQUEST_NEW_PASSWORD:
					sendSysMessage(CATEGORY.REGISTRATION, MESSAGE.SEND_NEW_PASSWORD, password);
					break;
				case REGISTRATION_SUCCESSFUL:
					System.out.println("Your registration was successful. Please login now using your new username.");
					break;
				case SEND_USER_LIST:
					if (sysMessage.getMessageObject() instanceof String[]) {
						String[] userList = (String[]) sysMessage.getMessageObject();
						System.out.printf("Users currently logged in: %s\n", Arrays.toString(userList));
					}
					break;
				case DISCONNECTED:
					System.out.println("["+sysMessage.getMessageString()+"] disconnected");
					break;
				case ALREADY_LOGGED_IN:
					System.out.println("you are already logged in");
					break;
				case USERNAME_ALREADY_EXISTS:
					System.out.println("username already in use try an other on");
					break;
				case LOGGED_OUT:
					System.out.println("["+sysMessage.getMessageString()+"] logged out");
					break;
				case USER_ALREADY_LOGGED_IN:
					System.out.println("this user is already logged in please try an other name");
					break;
				case NEW_USER_INFO:
					System.out.println(sysMessage.getMessageString()+" just connected");
					break;
				default:
					break;
				}			
			} else if (inputObject instanceof String){
				String temp=(String)inputObject;
				if (temp.isEmpty()==false)
					System.out.printf(temp);


				
			}
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
					reading=false;
					System.out.println("lost connection to server");
					try {
						server.close();
						server=null;
					} catch (IOException e1) {
						e1.printStackTrace();
					}
					this.disconnect();
				}
							
		}

		// TODO communication with server
	}

	/**
	 * @param msg
	 */
	public void sendMessage(Message msg) {
		connector.sendObject(msg);		
		return;
	}

	public void disconnect() {
		try {
			if(server!=null)this.server.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			this.finalize();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return;
	}

	
	public void sendSysMessage(SysMessage.CATEGORY cat, SysMessage.MESSAGE msg) {
		SysMessage sysMsg = new SysMessage(cat, msg);
		sysMsg.setSent(new Date());
		sysMsg.setSenderUsername(username);
		connector.sendObject(sysMsg);
	}
	
	public void sendSysMessage(SysMessage.CATEGORY cat, SysMessage.MESSAGE msg, String msgStr) {
		SysMessage sysMsg = new SysMessage(cat, msg, msgStr);
		sysMsg.setSent(new Date());
		sysMsg.setSenderUsername(username);
		connector.sendObject(sysMsg);
	}

}
